package com.example.wepaydemo;


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.security.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;


public class PayUtil {

	/**
	 * 统一接口
	 * @param url 微信请求url
	 * @param param 微信请求参数
	 * @return
	 * @throws IOException
	 */
	public static String request(String url, Object param) throws IOException {


		HttpPost httpPost = new HttpPost(url);
		//解决XStream对出现双下划线的bug
		XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
		xStreamForRequestPostData.alias("xml", param.getClass());
		//将要提交给API的数据对象转换成XML格式数据Post给API
		String postDataXML = xStreamForRequestPostData.toXML(param);

		System.out.println("--------------"+postDataXML);

		//得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
		StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
		httpPost.addHeader("Content-Type", "text/xml");
		httpPost.setEntity(postEntity);

		//设置请求器的配置
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(30000).build();
		httpPost.setConfig(requestConfig);

		HttpClient httpClient = HttpClients.createDefault();
		HttpResponse response = httpClient.execute(httpPost);


		HttpEntity entity = response.getEntity();
		String result = EntityUtils.toString(entity, "UTF-8");

		return result;

	}

	/**
	 * 处理退款申请外的接口
	 * @param url
	 * @param param 请求参数
	 * @param mch_id 商户号
	 * @return
	 * @throws KeyStoreException
	 * @throws IOException
	 * @throws UnrecoverableKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 */
	public static String refundRequest(String url,Object param,String mch_id) throws KeyStoreException, IOException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {

		StringBuilder sb = new  StringBuilder();
		//解决XStream对出现双下划线的bug
		XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
		xStreamForRequestPostData.alias("xml", param.getClass());
		//将要提交给API的数据对象转换成XML格式数据Post给API
		String postDataXML = xStreamForRequestPostData.toXML(param);
		//此处为p12证书 退款的时候能用到
		String path = PayUtil.class.getResource("/").getPath() + "apiclient_cert.p12";
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		FileInputStream inputStream = new FileInputStream(new File(path));
		try {
			keyStore.load(inputStream,mch_id.toCharArray());
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			inputStream.close();
		}

		// Trust own CA and all self-signed certs
		SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore,mch_id.toCharArray()).build();
		// Allow TLSv1 protocol only
		SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(
				sslContext,
				new String[]{"TLSv1"},
				null,
				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(factory).build();

		try {
			HttpPost httpPost  = new HttpPost(url);

			StringEntity  reqEntity  = new StringEntity(postDataXML);
			// 设置类型
			reqEntity.setContentType("application/x-www-form-urlencoded");

			httpPost.setEntity(reqEntity);

			CloseableHttpResponse response = httpclient.execute(httpPost);
			try {
				HttpEntity entity = response.getEntity();

				System.out.println(response.getStatusLine());
				if (entity != null) {
					BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
					String text;

					while ((text = bufferedReader.readLine()) != null) {
						sb.append(text);
					}

				}
				EntityUtils.consume(entity);
			} finally {
				response.close();
			}
		}finally {
			httpclient.close();
		}

		return sb.toString();

	}

}